package zybLog

import (
	"fmt"
	"github.com/lestrrat/go-file-rotatelogs"
	"github.com/rifflock/lfshook"
	"github.com/sirupsen/logrus"
	"os"
	"path/filepath"
	"time"
	"strings"
	"runtime"
	"bytes"
	"strconv"
)

type ZybLog struct {
	logger *logrus.Logger
	logWriter *rotatelogs.RotateLogs
}

type zybFormat struct {}

func (l *zybFormat)Format(entry *logrus.Entry)([]byte, error)  {
	timestamp := time.Now().Local().Format("2006-01-02 15:04:06")
	var filename string
	var linenum int
	if entry.Caller != nil {
		filename = filepath.Base(entry.Caller.File)
		linenum = entry.Caller.Line
	}

	msg := fmt.Sprintf("|%s|%s|%d|%s:%d|%s|\n", timestamp, strings.ToUpper(entry.Level.String()),
		getThreadID(), filename, linenum, entry.Message)

	return []byte(msg), nil
}

func getThreadID() uint64 {
	b := make([]byte, 64)
	b = b[:runtime.Stack(b, false)]
	b = bytes.TrimPrefix(b, []byte("goroutine "))
	b = b[:bytes.IndexByte(b, ' ')]
	n, _ := strconv.ParseUint(string(b), 10, 64)
	return n
}

func (t *ZybLog)Init() bool {
	err := os.MkdirAll("./log", os.ModePerm)
	if err != nil {
		fmt.Println("os mkdirall fail:", err)
		return false
	}

	t.logger = logrus.New()
	logName := filepath.Join("./log","test")

	fmt.Println("logName:", logName)

	t.logger.SetReportCaller(true)

	// set output.
	{
		src, err := os.OpenFile(os.DevNull, os.O_APPEND | os.O_WRONLY , os.ModeAppend)
		if err != nil {
			fmt.Println("os open file fail:", err)
			return false
		}

		t.logger.SetOutput(src)
	}

	t.logger.SetLevel(logrus.DebugLevel)

	t.logWriter, err = rotatelogs.New(
		logName + "_%Y-%m-%d.log",
		rotatelogs.WithMaxAge(7*24*time.Hour),
		rotatelogs.WithRotationTime(24*time.Hour),
	)

	if err != nil {
		fmt.Println("rotatelogs writer fail:", err)
		return false
	}

	writeMap := lfshook.WriterMap{
		logrus.PanicLevel: t.logWriter,
		logrus.FatalLevel: t.logWriter,
		logrus.ErrorLevel: t.logWriter,
		logrus.WarnLevel:  t.logWriter,
		logrus.InfoLevel:  t.logWriter,
		logrus.DebugLevel: t.logWriter,
		logrus.TraceLevel: t.logWriter,
	}

	/*hook := lfshook.NewHook(writeMap, &logrus.TextFormatter{
		TimestampFormat: "2006-01-02 15:04:05",
	})*/

	hook := lfshook.NewHook(writeMap, new(zybFormat))

	t.logger.AddHook(hook)

	return true

	//logger.Debugf("how are you?")
}

func (t *ZybLog)Logger() *logrus.Logger {
	return t.logger
}